package main

import (
	"fmt"       // Go语言标准库中的包
	"io/ioutil" // 包含一些输入输出函数
	// 数学标准库，在此文件中别名为m
	"net/http" // 一个web服务器包
	"os"       // 系统底层函数，如文件读写
	"strconv"  // 字符串转换
)

func main() {
	fmt.Println("天坑欢迎我")
	beyondHello()
}
func beyondHello() {
	var x int
	x = 3
	y := 4
	sum, prod := learnMultiple(x, y)
	fmt.Println("sum", sum, "prod", prod)
}
func learnMultiple(x, y int) (sum, prod int) {
	return x + y, x * y
}
func learnTypes() {
	str := "少说话多读书!"
	fmt.Println(str)
	// s2 := '这是一个
	// 可以换行的字符串'
	f := 3.1415926
	fmt.Println(f)
	c := 3 + 4i
	var u int = 7
	fmt.Println(u)
	var pi float32 = 22. / 7
	fmt.Println(pi)
	n := byte('\n')
	fmt.Println(n)
	var a4 [4]int
	a3 := [...]int{3, 1, 5}
	fmt.Println(a3)
	s3 := []int{4, 5, 9}
	var d2 [][]float64
	bs := []byte("a slice")
	fmt.Println(bs)
	s := []int{1, 2, 3}
	s = append(s, 4, 5, 6)
	fmt.Println(s)
	s = append(s, []int{7, 8, 9}...)
	fmt.Println(s)
	p, q := learnMemory()
	fmt.Println(*p, *q)
	m := map[string]int{"three": 3, "four": 4}
	m["one"] = 1
	file, _ := os.Create("output.txt")
	fmt.Fprint(file, "我认识最狠的人乃是老渣，我渣哥")
	file.Close()
	fmt.Println(s, c, a4, s3, d2, m)
	learnFlowControl()
}
func learnNamedReturns(x, y int) (z int) {
	z = x * y
	return
}
func learnMemory() (p, q *int) {
	p = new(int)
	s := make([]int, 20)
	s[3] = 7
	r := -2
	return &s[3], &r
}
func expensiveComputation() int {
	return 1e6
}
func learnFlowControl() {
	if true {
		fmt.Println("这句话肯定被执行")
	}
	if false {

	} else {

	}
	x := 1
	switch x {
	case 0:
	case 1:
	case 2:
	}

	for x := 0; x < 3; x++ {
		fmt.Println("遍历", x)
	}
	for {
		break
		continue
	}
	for key, value := range map[string]int{"one": 1, "two": 2, "three": 3} {
		fmt.Printf("索引: %s,值为:%d\n", key, value)
	}
	for _, name := range []string{"Bob", "Bill", "Joe"} {
		fmt.Printf("你是.. %s\n", name)
	}
	if y := expensiveComputation(); y > x {
		x = y
	}
	xBig := func() bool {
		return x > 100
	}
	fmt.Println("xBig", xBig())
	x /= 1e5
	fmt.Println("xBig", xBig())
	fmt.Println(
		"两数相加乘二",
		func(a, b int) int {
			return (a + b) * 2
		}(10, 2))

	goto love
love:
	learnFunctionFactory()
	learnDefer()
	learnInterfaces()
}
func learnFunctionFactory() {
	fmt.Println(sentenceFactory("原谅")("当然选择", "她!"))
	d := sentenceFactory("原谅")
	fmt.Println(d("当然选择", "她!"))
	fmt.Println(d("你怎么可以", "她"))
}
func sentenceFactory(mystring string) func(before, after string) string {
	return func(brefore, after string) string {
		return fmt.Sprintf("%S %s %S", brefore, mystring, after)
	}
}
func learnDefer() (ok bool) {
	defer fmt.Println("defer表达式执行顺序为先进后出 (LIFO)")
	defer fmt.Println("\n这句话比上句话先输出,因为")
	return true

}

type Stringer interface {
	String() string
}
type pair struct {
	x, y int
}

func (p pair) String() string {
	return fmt.Sprintf("(%d,%d)", p.x, p.y)
}
func learnInterfaces() {
	p := pair{3, 4}
	fmt.Println(p.String())
	var i Stringer
	i = p
	fmt.Println(i.String())
	fmt.Println(p)
	fmt.Println(i)
	learnVariadicParams("great", "learning", "here!")
}

// 有变长参数列表的函数
func learnVariadicParams(myStrings ...interface{}) {
	// 枚举变长参数列表的每个参数值
	// 下划线在这里用来抛弃枚举时返回的数组索引值
	for _, param := range myStrings {
		fmt.Println("param:", param)
	}

	// 将可变参数列表作为其他函数的参数列表
	fmt.Println("params:", fmt.Sprintln(myStrings...))

	learnErrorHandling()
}
func learnErrorHandling() {
	m := map[int]string{3: "three", 4: "four"}
	if x, ok := m[1]; !ok {
		fmt.Println("别找了没有的")
	} else {
		fmt.Print(x)
	}
	if _, err := strconv.Atoi("non-int"); err != nil {
		fmt.Println(err)
	}
	learnConcurrency()
}
func inc(i int, c chan int) {
	c <- i + 1
}
func learnConcurrency() {
	c := make(chan int)
	go inc(0, c)
	go inc(10, c)
	go inc(-805, c)
	fmt.Println(<-c, <-c, <-c)
	cs := make(chan string)
	cc := make(chan chan string)
	go func() { c <- 84 }()
	go func() { cs <- "wordy" }()
	select {
	case i := <-c:
		fmt.Println("这是.....", i)
	case <-cs:
		fmt.Println("这是一个字符串!")

	case <-cc:
		fmt.Println("别瞎想")
	}
	learnWebProgramming()
}
func learnWebProgramming() {
	go func() {
		err := http.ListenAndServe(":8080", pair{})
		fmt.Println(err) //不要无视错误
	}()
	requestServer()
}
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Y分钟Golang速成!"))
}
func requestServer() {
	resp, err := http.Get("http://localhost:80880")
	fmt.Println(err)
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	fmt.Printf("\n服务器消息: '%s'", string(body))
}
